package jacky.lanlan.song.util.codec;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.HashMap;
import java.util.Map;

public enum NormalCodec {
	
	HEX {
		@Override
		public String encode(String data) {
			if (data == null) return null;
			return this.encode(data.getBytes());
		}
		
		@Override
		public String encode(byte[] bytes) {
			StringBuilder buffer = new StringBuilder(bytes.length * 2);
			for (int i = 0; i < bytes.length; i++) {
				if ((bytes[i] & 0xff) < 0x10) buffer.append("0");
				buffer.append(Long.toString(bytes[i] & 0xff, 16));
			}
			return buffer.toString().toUpperCase();
		}
	},
	
	SHA {
		@Override
		public String encode(String data) {
			if (data == null) return null;
			return this.encode(data.getBytes());
		}
		
		@Override
		public String encode(byte[] data) {
			if (data == null) return null;
			try {
				MessageDigest md = MessageDigest.getInstance("SHA");
				return new String(HEX.encode(md.digest(data))).toUpperCase();
			}
			catch (NoSuchAlgorithmException e) {
				throw new RuntimeException(e);
			}
		}
	},
	
	MD5 {
		@Override
		public String encode(String data) {
			if (data == null) return null;
			return this.encode(data.getBytes());
		}
		
		@Override
		public String encode(byte[] data) {
			if (data == null) return null;
			try {
				MessageDigest md = MessageDigest.getInstance("MD5");
				return new String(HEX.encode(md.digest(data))).toUpperCase();
			}
			catch (NoSuchAlgorithmException e) {
				throw new RuntimeException(e);
			}
		}
	},
	
	Base64 {
		@Override
		public String encode(String data) {
			return Base64Codec.encode(data);
		}
		
		@Override
		public String encode(byte[] data) {
			return new String(Base64Codec.encode(data));
		}
		
		@Override
		public String decode(byte[] data) {
			return new String(Base64Codec.decode(new String(data)));
		}
		
		@Override
		public String decode(String data) {
			return new String(Base64Codec.decode(data));
		}
	}

	;
	
	public abstract String encode(String data);
	
	public abstract String encode(byte[] data);
	
	public String decode(String data) {
		throw new UnsupportedOperationException();
	}
	
	public String decode(byte[] data) {
		throw new UnsupportedOperationException();
	}
	
	public static Map<String, String> encodeAll(String data) {
		Map<String, String> map = new HashMap<String, String>(3, 1);
		for (NormalCodec codec : values()) {
			map.put(codec.name(), codec.encode(data));
		}
		return map;
	}
	
}
